// /*
//  * @Author: WanYiMing
//  * @Date:2024-03-01-13:56
//  * @Description:
//  */

using System;
using System.Collections.Generic;
using Code.Core.CoreBaseClass;

namespace Code.Core.StateMachine
{
    public abstract class BaseFsmV2<TFsm> : BaseController where TFsm : BaseFsmV2<TFsm>
    {
        private Dictionary<Type, object> _states = new Dictionary<Type, object>();

        private State<TFsm> _onState;

        private State<TFsm> _initState;

        public TFsm tFsm;
        public abstract void InitStates();
        public abstract void InitTFsm();


        private void Awake()
        {
            InitTFsm();
            InitStates();
        }

        private void Update()
        {
            AutoSwitchState();
            _onState.HoldState();
        }

        private void AutoSwitchState()
        {
            if (_onState.CheckState() && _onState.LastState != null)
            {
                //切换到下一个状态
                AutoSwitchState(_onState.LastState);
            }

            if (_onState.CheckState() && _onState.LastState == null)
            {
                //回到初始状态
                AutoSwitchState(_initState);
            }
        }


        public void AutoSwitchState(State<TFsm> state)
        {
            if (_onState.GetType() == state.GetType())
            {
                return;
            }
            ExeSwitch(_onState, state);
        }


        
        public void SwitchState(Type type)
        {
            if (_onState.GetType() == type)
            {
                return;
            }
            //外部切换是保护的  
            if (_onState.IsProtective())
            {
                return;
            }

            State<TFsm> state = GetState(type);
            ExeSwitch(_onState,state);
        }
        
        public void SwitchState<TState>()
        {
            Type type = typeof(TState);
            SwitchState(type);
        }

        private void ExeSwitch(State<TFsm> onState,State<TFsm> lastState)
        {
            onState.OutState();
            lastState.InState();
            _onState = lastState;
        }


        public State<TFsm> GetState<TState>()
        {
            var key = typeof(TState);
            return GetState(key);
        }

        
        
        
        public State<TFsm> GetState(Type type)
        {
            if (_states.TryGetValue(type, out var retInstance))
            {
                return retInstance as State<TFsm>;
            }

            return null;
        }

        public void AddState<TState>() where TState : State<TFsm> , new()
        {
            var key = typeof(TState);
            State<TFsm>  state = new TState();
            AddState<TState>(state);
        }

        public void AddState<TStruct>(State<TFsm> instance)
        {
            var key = typeof(TStruct);

            if (_states.ContainsKey(key))
            {
                _states[key] = instance;
            }
            else
            {
                _states.Add(key, instance);
            }

            instance.StateFsm =tFsm;
            SetInitState(instance);
        }

        public void SetLastState<TAState, TBState>()
        {
            State<TFsm> tstate = GetState<TAState>();
            tstate.LastState=GetState<TBState>();
        }
        
        public void SetLastState(Type taState,Type tbState)
        {
            State<TFsm> tstate = GetState(taState);
            tstate.LastState=GetState(tbState);
        }



        private void SetInitState(State<TFsm> instance)
        {
            if (instance.IsInitState())
            {
                _onState = instance;
                _initState = instance;
            }
        }

        public State<TFsm> GetOnState()
        {
            return _onState;
        }


    }
}